/**
 * @author WY
 * @since 2024/03
 */

import { ParameterObjectType } from '@amcax/base';
import { DimLabel, DimLabelProps } from './DimLabel';
import { THREE } from '@amcax/web-render';
import { DimCallback } from '../type';
import { CSS2DReactObject } from '@/components/Css2dReactObject/CSS2DReactObject';

export type css2dInputLabelAttrs = {
  multiple?: number; // 类型
  id?: string | number; // 对应的id
  onfocus?: boolean; // 是否处于激活状态
  inputType?: ParameterObjectType;
} & updateAttrs;
type updateAttrs = {
  prefix?: string;
  text?: number;
  position?: THREE.Vector3;
  callback?: DimCallback;
};
export class CS2DInputLabel {
  object: CSS2DReactObject<DimLabelProps>; // css2dObject对象
  isActive: boolean = false; // 是否处于激活状态
  text: number; // 最终数值内容
  scene: THREE.Object3D; // 场景对象
  prefix: string = ''; // 前缀
  inputType: ParameterObjectType;
  type: string; // 类型
  multiple: number = 1; // 乘数
  divHtml: HTMLDivElement;
  dimId: string | number;

  callback: DimCallback;
  constructor(attrs?: css2dInputLabelAttrs) {
    this.init(attrs);
  }

  updateDimLabelProps(props: Partial<DimLabelProps>) {
    this.object.updateProps({
      ...this.object.props,
      ...props,
    });
  }

  setDisable(isDisable: boolean) {
    this.updateDimLabelProps({
      disabled: isDisable,
      isEdit: false,
    });
  }
  getType() {
    return 'CS2DInputLabel';
  }

  setHover(hovered: boolean) {
    this.updateDimLabelProps({
      hovered,
    });
  }

  setSelected(selected: boolean) {
    if (selected === this.object.props.selected) {
      return;
    }

    this.updateDimLabelProps({
      selected,
      isEdit: false,
    });
  }

  init(attrs?: css2dInputLabelAttrs) {
    this.multiple = attrs.multiple || 1; // 单位倍数
    this.prefix = attrs.prefix || ''; // 前置标记
    this.dimId = attrs.id || ''; // 标注id
    this.callback = attrs.callback; // 回调函数
    this.isActive = attrs.onfocus || false; // 是否获取焦点
    this.inputType = attrs.inputType ?? ParameterObjectType.Real;
    this.text = Math.abs(attrs.text || 0);
    // 标注的位置
    this.createCss2DObject(attrs.position); // 创建css2d对象
    this.updateText(this.text); // 设置文本
  }
  private updateText(text: number) {
    this.updateDimLabelProps({
      value: text,
    });
  }

  private createCss2DObject(pos: THREE.Vector3) {
    this.divHtml = document.createElement('div');
    this.divHtml.id = `${'divHtml'}_${this.dimId ? this.dimId : 'container'}`;
    this.divHtml.className = '_label-input-bg';

    this.object = new CSS2DReactObject<DimLabelProps>(this.divHtml, DimLabel, {
      type: this.inputType,
      prefix: this.prefix,
      disabled: false,
      isEdit: false,
      value: 0,
      allowActive: true,
      hovered: false,
      selected: false,
      onChange: (active, text) => {
        if (text != null) {
          this.text = text;
        }
        if (!active && text != null && this.isActive) {
          this.callback?.('blur', text);
          this.setVisibility(true);
        } else {
          this.callback?.(active ? 'focus' : 'blur');
          this.setVisibility(!active);
        }
        this.isActive = active;
        this.updateDimLabelProps({ isEdit: active });
      },
      multiple: this.multiple,
    });

    this.object.position.set(pos.x, pos.y, pos.z);
    this.object.name = 'CS2DInputLabel';
  }
  getLabelWH() {
    return {
      width: this.divHtml.offsetWidth,
      height: this.divHtml.offsetHeight,
    };
  }

  update({ prefix, text, position: pos, callback }: updateAttrs) {
    prefix && (this.prefix = prefix);
    if (text || text === 0) {
      this.updateText(Math.abs(text));
    }
    if (callback) {
      this.callback = callback;
    }
    if (pos) {
      this.object.position.set(pos.x, pos.y, pos.z);
    }
  }
  // 设置激活
  focus() {
    if (!this.isActive) {
      this.isActive = true; // 设置激活状态
      this.updateDimLabelProps({
        isEdit: true,
      });
      this.setVisibility(false);
    }
  }

  // 设置失焦
  blur() {
    this.updateDimLabelProps({
      isEdit: false,
    });
    this.setVisibility(true);
  }
  // 允许click激活
  clickFocus() {
    this.updateDimLabelProps({
      allowActive: true,
    });
  }
  // 不允许click激活
  unClickFocus() {
    this.updateDimLabelProps({
      allowActive: false,
    });
  }
  // 获取当前数值
  getText() {
    return this.text;
  }

  // 销毁当前对象
  destroy() {
    this.scene?.remove(this.object);
  }
  /**
   * @description 添加到场景中去
   * @param { Object3D } scene
   **/
  addTo(scene: THREE.Object3D) {
    this.scene = scene;
    this.scene.add(this.object);
  }
  setVisibility(visible: boolean) {
    this.divHtml.style.visibility = visible ? 'visible' : 'hidden';
  }
  hide() {
    this.object.visible = false;
  }
  show() {
    this.object.visible = true;
  }
}
